﻿/*--------------------------------------------------------------*                                       
 *--------------------------------------------------------------*/

#ifndef _FlashToEEP_H_
#define _FlashToEEP_H_

#include <stdint.h>
#include "rtctime.h"

#define FLASH_EEP_ERR_NONE 0
#define FLASH_EEP_ERR_SECSIZE 1 /*扇区尺寸错误*/
#define FLASH_EEP_ERR_EEPSIZE 2 /*EEP数量错误*/
#define FLASH_EEP_ERR_BLKSIZE 3 /*数据块空间*/
#define FLASH_EEP_ERR_DATSIZE 4 /*实际数据个数*/
#define FLASH_EEP_ERR_EEPBASE 5 /*基址错误,基址未对齐到扇区边界*/
#define FLASH_EEP_ERR_DATOVE 6  /*数据尺寸大于eep尺寸*/
#define FLASH_EEP_ERR_DATOVK 7  /*数据尺寸大于数据块*/
#define FLASH_EEP_ERR_BLKOVE 8  /*数据块大于EEP空间*/
#define FLASH_EEP_ERR_DATPER 9  /*数据尺寸必须为4的倍数*/
#define FLASH_EEP_ERR_EMPTY 10  /*扇区全空 ,表示从未写过数据*/
#define FLASH_EEP_ERR_DATBL 11  /*数据块太小，至少为4*/
#define FLASH_EEP_ERR_EEPSST 12 /*EEP尺寸不是扇区的倍数*/
#define FLASH_EEP_ERR_EXTPAG 13 /*EEP尺寸不是扇区的倍数*/

/*--------------------------------------------Inner Flash to eep-----------------------------------------------*/
typedef struct
{
    uint32_t Site;          /*当前指向的位置*/
    uint32_t Blocks;        /*分割块数*/
    uint16_t Err;           /*上次错误代码*/
    uint16_t Checked;       /*参数已经通过检测*/
} FlashEepInfo_Type;

typedef struct
{
    uint32_t SectorSize;                             /*扇区擦除尺寸 ,2^n边界对齐  必须和硬件物理参数一致,字节数 */
    uint32_t EepSize;                                /*虚拟Eep尺寸  ,扇区尺寸的2^n倍数  字节数*/
    uint32_t DataBlockSize;                          /*每组数据块占用空间 ,2^边界对齐 ,字节数 ，使用多块管理时，数据块用空余4字节用于存储校验，对于单一模式此值最小为4，muti模式最小为8*/
    uint32_t DataSize;                               /*实际数据块尺寸,必须为4的倍数  字节数*/
    uint32_t EepBase;                                /*虚拟Eep基址  ,扇区边界对齐*/
    uint16_t *Data;                                  /*数据源，实际尺寸应大于等于DataSize*/
    FlashEepInfo_Type *Info;                         /*运行时信息*/
    void (*Erase)(uint32_t AddrBase); /*从指定地址擦除，Nums指定擦除的扇区个数*/
    void (*Program)(uint32_t Addr, uint32_t Data);   /*向指定指定地址编程数据*/
    void (*Unlock)(void);                            /*flash解锁  0不执行*/
    void (*Lock)(void);                              /*flash锁定  0不执行*/
} FlashEepCfg_Type;

uint16_t FlashEepRead(const FlashEepCfg_Type *EepCfg);
uint16_t FlashEepSave(const FlashEepCfg_Type *EepCfg);

uint16_t FlashMulEepSave(const FlashEepCfg_Type *EepCfg);
uint16_t FlashMulEepRead(const FlashEepCfg_Type *EepCfg);

/*--------------------------------------------ext Flash to eep-----------------------------------------------*/
/* 内部 calloc 最大 data block size*/
typedef struct
{
    uint32_t Site;          /*当前指向的位置*/
    uint32_t Blocks;        /*分割块数*/
    uint16_t Err;           /*上次错误代码*/
    uint16_t Checked;       /*参数已经通过检测*/
} ExtFlashEepInfo_Type;

typedef struct
{
	uint32_t EepBase;       /*虚拟Eep基址  ,扇区边界对齐*/
	uint32_t EepSize;       /*虚拟Eep尺寸  ,扇区尺寸的2^n倍数  字节数*/
    uint32_t SectorSize;    /*扇区擦除尺寸 ,2^n边界对齐  必须和硬件物理参数一致,字节数 */
    uint32_t DataBlockSize; /*每组数据块占用空间 ,2^边界对齐 ,字节数*/
    uint32_t DataSize;      /*实际数据块尺寸,必须为2的倍数，+4<=DataBlockSize */
    void *Data;          	/*数据源，实际尺寸应大于等于DataSize,前2字节不允许全为0xFF，用以确认数据是否保存程序，防止存数据过程中断电导致数据不完整*/
    ExtFlashEepInfo_Type *Info;                                  /*运行时信息*/
    uint8_t (*Erase)(uint32_t AddrBase);             /*从指定地址擦除，Nums指定擦除的扇区个数*/
    uint8_t (*Program)(uint32_t Addr, uint8_t *Data, uint16_t Len); /*向指定指定地址编程数据*/
    uint8_t (*Read)(uint32_t Addr, uint8_t *Data, uint16_t Len);
} ExtFlashEepCfg_Type;

uint16_t ExtFlashMulEepSave(const ExtFlashEepCfg_Type *EepCfg);
uint16_t ExtFlashMulEepRead(const ExtFlashEepCfg_Type *EepCfg);

#endif
